/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package ssp.agent;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import ssp.net.NWcomponent;
import ssp.service.FrontendServer;
import ssp.strategy.agent.Agent_v1_Strategy_v1;
import ssp.topology.Node;
import ssp.utility.Pair;

/**
 *
 * @author yamazaki
 */
public class Agent_v1 {
    
    private final NWcomponent belongingNWcomponent;
    
    private final Agent_v1_Strategy_v1 strategy;
    
    private final QualityRequirement qualityRequirement;
    
    private List<FrontendServer> candidateServiceList;
    
    private Map<Double, Pair<FrontendServer, List<NWcomponent>>> candidatePath;
    
    public Agent_v1(NWcomponent belongingNWcomponent, QualityRequirement qualityRequirement, Agent_v1_Strategy_v1 strategy) {
        this.belongingNWcomponent = belongingNWcomponent;
        this.qualityRequirement = qualityRequirement;
        this.candidateServiceList = new ArrayList<FrontendServer>();
        this.candidatePath = new TreeMap<Double, Pair<FrontendServer, List<NWcomponent>>>();
        this.strategy = strategy;
    }
    
    public boolean createServicePath(int frontendServerNum) {
        searchFrontendServer(frontendServerNum);
        searchPath();
        if(candidatePath.isEmpty()) {
            return false;
        }
        return makeService();
    }
    
    private void searchFrontendServer(int num) {
        candidateServiceList = new ArrayList<FrontendServer>(strategy.searchFrontendServer(qualityRequirement, belongingNWcomponent, num));
    }
    
    private void searchPath() {
        for(FrontendServer frontendServer : candidateServiceList) {
            
            Pair<FrontendServer, List<NWcomponent>> path = strategy.searchPath(qualityRequirement, belongingNWcomponent, frontendServer);
            
            //↓マップ？？
//            double chargeSum = entry.getKey().getServiceEntry(entry.getValue()).getCharge();
//            Node prevNode = belongingNWcomponent;
//            NWcomponent node = path.getSecond().get(2);
//            
//            for(NWcomponent nextNode : path.getSecond()) {
//                if(path.getSecond().indexOf(nextNode) == 0 || path.getSecond().indexOf(nextNode) == 1) {
//                    continue;
//                }
//                chargeSum += node.getNWresourceManager().getCharge(prevNode, nextNode, qualityRequirement.getBandwidth());
//                prevNode = node;
//                node = nextNode;
//            }
//            
//            candidatePath.put(chargeSum, path);
        }
    }
    
    private boolean makeService() {
        Pair<FrontendServer, List<NWcomponent>> lowestCost = new Pair(((TreeMap<Double, Pair<FrontendServer, List<NWcomponent>>>)(candidatePath)).firstEntry().getValue());
        return strategy.makeService(lowestCost.getFirst(), new ArrayList<NWcomponent>(lowestCost.getSecond()));
    }
    
}
